package org.light.verb;

import java.util.ArrayList;
import java.util.List;

import org.light.core.Verb;
import org.light.core.Writeable;
import org.light.domain.Domain;
import org.light.domain.JavascriptBlock;
import org.light.domain.JavascriptMethod;
import org.light.domain.Method;
import org.light.domain.Signature;
import org.light.domain.Statement;
import org.light.domain.StatementList;
import org.light.domain.Type;
import org.light.domain.Var;
import org.light.easyui.EasyUIPositions;
import org.light.exception.ValidateException;
import org.light.generator.NamedStatementGenerator;
import org.light.generator.NamedStatementListGenerator;
import org.light.limitedverb.CountAllPage;
import org.light.utils.InterVarUtil;
import org.light.utils.MybatisSqlReflector;
import org.light.utils.StringUtil;
import org.light.utils.WriteableUtil;

public class ListAllByPage extends Verb implements EasyUIPositions {
	protected CountAllPage countAllPage;

	public CountAllPage getCountAllPage() {
		return countAllPage;
	}

	public void setCountAllPage(CountAllPage countAllPage) {
		this.countAllPage = countAllPage;
	}

	@Override
	public Method generateDaoImplMethod() throws Exception {
		if (this.denied)
			return null;
		else {
			Method method = new Method();
			method.setStandardName("listAll" + StringUtil.capFirst(this.domain.getPlural()) + "ByLimit");
			method.setNoContainer(true);
			List<Writeable> list = new ArrayList<Writeable>();
			list.add(new Statement(100L, 1,
					"<select id=\"" + StringUtil.lowerFirst(generateDaoMethodDefinition().getLowerFirstMethodName())
							+ "\" resultMap=\"" + this.domain.getLowerFirstDomainName() + "\">"));
			list.add(new Statement(200L, 2, MybatisSqlReflector.generateSelectAllByLimitStatement(domain)));
			list.add(new Statement(300L, 1, "</select>"));
			method.setMethodStatementList(WriteableUtil.merge(list));
			return method;
		}
	}

	@Override
	public String generateDaoImplMethodString() throws Exception {
		if (this.denied)
			return null;
		else {
			Method m = this.generateDaoImplMethod();
			String s = m.generateMethodString();
			return s;
		}
	}

	@Override
	public Method generateDaoMethodDefinition() throws Exception {
		if (this.denied)
			return null;
		else {
			Method method = new Method();
			method.setStandardName("listAll" + StringUtil.capFirst(this.domain.getPlural()) + "ByLimit");
			method.setReturnType(new Type("List", this.domain, this.domain.getPackageToken()));
			method.addAdditionalImport("java.util.List");
			method.addAdditionalImport(this.domain.getPackageToken() + "." + this.domain.getDomainSuffix() + "."
					+ this.domain.getCapFirstDomainNameWithSuffix());
			method.addSignature(new Signature(1, "start", new Type("Integer").getClassType()));
			method.addSignature(new Signature(2, "limit", new Type("Integer").getClassType()));
			method.setThrowException(true);
			return method;
		}
	}

	@Override
	public String generateDaoMethodDefinitionString() throws Exception {
		if (this.denied)
			return null;
		else {
			return generateDaoMethodDefinition().generateMethodDefinition();
		}
	}

	@Override
	public String generateDaoImplMethodStringWithSerial() throws Exception {
		if (this.denied)
			return null;
		else {
			Method m = this.generateDaoImplMethod();
			m.setContent(m.generateMethodContentStringWithSerial());
			m.setMethodStatementList(null);
			return m.generateMethodString();
		}
	}

	@Override
	public Method generateServiceMethodDefinition() throws Exception {
		if (this.denied)
			return null;
		else {
			Method method = new Method();
			method.setStandardName("listAll" + StringUtil.capFirst(this.domain.getPlural()) + "ByPage");
			method.setReturnType(new Type("List", this.domain, this.domain.getPackageToken()));
			method.addAdditionalImport("java.util.List");
			method.addAdditionalImport(this.domain.getPackageToken() + "." + this.domain.getDomainSuffix() + "."
					+ this.domain.getCapFirstDomainNameWithSuffix());
			method.addSignature(new Signature(1, "pagesize", new Type("Integer").getClassType()));
			method.addSignature(new Signature(2, "pagenum", new Type("Integer").getClassType()));
			method.setThrowException(true);

			return method;
		}
	}

	@Override
	public String generateServiceMethodDefinitionString() throws Exception {
		if (this.denied)
			return null;
		else {
			return generateServiceMethodDefinition().generateMethodDefinition();
		}
	}

	@Override
	public Method generateServiceImplMethod() throws Exception {
		if (this.denied)
			return null;
		else {
			Method method = new Method();
			method.setStandardName("listAll" + StringUtil.capFirst(this.domain.getPlural()) + "ByPage");
			method.setReturnType(new Type("List", this.domain, this.domain.getPackageToken()));
			method.addSignature(new Signature(1, "pagesize", new Type("Integer").getClassType()));
			method.addSignature(new Signature(2, "pagenum", new Type("Integer").getClassType()));
			method.addAdditionalImport("java.util.List");
			method.addAdditionalImport(this.domain.getPackageToken() + "." + this.domain.getDomainSuffix() + "."
					+ this.domain.getCapFirstDomainNameWithSuffix());
			method.addAdditionalImport(this.domain.getPackageToken() + "." + this.domain.getDaoSuffix() + "."
					+ this.domain.getStandardName() + "Dao");
			method.addAdditionalImport(this.domain.getPackageToken() + "." + this.domain.getServiceSuffix() + "."
					+ this.domain.getStandardName() + "Service");
			method.setThrowException(true);
			method.addMetaData("Override");

			Method daomethod = this.generateDaoMethodDefinition();

			List<Writeable> list = new ArrayList<Writeable>();
			list.add(new Statement(1000L, 2, "Integer start = (pagenum-1)*pagesize;"));
			list.add(new Statement(2000L, 2, "Integer limit = pagesize;"));
			list.add(new Statement(3000L, 2, "return "
					+ daomethod.generateStandardServiceImplCallString(InterVarUtil.DB.dao.getVarName()) + ";"));
			method.setMethodStatementList(WriteableUtil.merge(list));

			return method;
		}
	}

	@Override
	public String generateServiceImplMethodString() throws Exception {
		if (this.denied)
			return null;
		else {
			return generateServiceImplMethod().generateMethodString();
		}
	}

	@Override
	public String generateServiceImplMethodStringWithSerial() throws Exception {
		if (this.denied)
			return null;
		else {
			Method m = this.generateServiceImplMethod();
			m.setContent(m.generateMethodContentStringWithSerial());
			m.setMethodStatementList(null);
			return m.generateMethodString();
		}
	}

	public ListAllByPage(Domain domain) throws ValidateException{
		super();
		this.domain = domain;
		this.denied = true;
		this.setVerbName("ListAll" + StringUtil.capFirst(this.domain.getPlural()) + "ByPage");
		this.countAllPage = new CountAllPage(this.domain);
		if (this.noControllerVerbs.size() == 0)
			this.noControllerVerbs.add(this.countAllPage);
		this.setLabel("分页列出");
		if  (domain.getLanguage().equalsIgnoreCase("english"))  this.setLabel("ListAllByPage");
	}

	public ListAllByPage() {
		super();
		this.setLabel("分页列出");
	}

	@Override
	public Method generateControllerMethod() throws Exception {
		if (this.denied)
			return null;
		else {
			Method method = new Method();
			method.setStandardName("listAll" + StringUtil.capFirst(this.domain.getPlural()) + "ByPage");
			method.setReturnType(new Type("Map<String,Object>"));
			method.setThrowException(true);
			method.addAdditionalImport("java.util.List");
			method.addAdditionalImport(this.domain.getPackageToken() + "." + this.domain.getDomainSuffix() + "."
					+ this.domain.getCapFirstDomainNameWithSuffix());
			method.addAdditionalImport(this.domain.getPackageToken() + "." + this.domain.getServiceSuffix() + "."
					+ this.domain.getStandardName() + "Service");
			method.addSignature(new Signature(1, "pagenum", new Type("Integer").getClassType(), "", "RequestParam"));
			method.addSignature(new Signature(2, "pagesize", new Type("Integer").getClassType(), "", "RequestParam"));
			method.addSignature(new Signature(3, "lastFlag", new Type("Boolean").getClassType(), "", "RequestParam"));
			method.addMetaData("RequestMapping(value = \"/" + StringUtil.lowerFirst(method.getStandardName())
					+ "\", method = RequestMethod.POST)");

			List<Writeable> wlist = new ArrayList<Writeable>();
			Var service = new Var("service",
					new Type(this.domain.getStandardName() + "Service", this.domain.getPackageToken()));
			Var vlist = new Var(StringUtil.lowerFirst(this.domain.getStandardName()) + "List",
					new Type("List", this.domain, this.domain.getPackageToken()));
			Method serviceMethod = this.generateServiceMethodDefinition();
			Var pagesize = new Var("pagesize", new Type("Integer"), "10");
			Var pagenum = new Var("pagenum", new Type("Integer"), "1");
			Var pagecount = new Var("pagecount", new Type("Integer"));
			Var resultMap = new Var("result", new Type("TreeMap<String,Object>", "java.util"));
			Var lastFlag = new Var("lastFlag", new Type("boolean"));
			wlist.add(new Statement(1000L, 2, "if (" + pagesize.getVarName() + "==null || " + pagesize.getVarName()
					+ " <= 0) " + pagesize.getVarName() + " = 10;"));
			wlist.add(NamedStatementGenerator.getJsonResultMap(2000L, 2, resultMap));
			wlist.add(new Statement(3000L, 2, pagecount.generateTypeVarString() + " = " + service.getVarName() + "."
					+ this.countAllPage.generateServiceMethodDefinition().getStandardCallString() + ";"));
			wlist.add(new Statement(4000L, 2, "if (" + pagenum.getVarName() + "==null || " + pagenum.getVarName()
					+ " <= " + pagenum.getValue() + ") " + pagenum.getVarName() + " = " + pagenum.getValue() + ";"));
			wlist.add(new Statement(5000L, 2, "if (" + pagenum.getVarName() + " >= " + pagecount.getVarName() + ") "
					+ pagenum.getVarName() + " = " + pagecount.getVarName() + ";"));
			wlist.add(new Statement(5500L, 2, "if (" + lastFlag.getVarName() + ") " + pagenum.getVarName() + " = "
					+ pagecount.getVarName() + ";"));
			wlist.add(new Statement(6000L, 2, vlist.generateTypeVarString() + " = "
					+ serviceMethod.generateStandardServiceImplCallString(InterVarUtil.DB.service.getVarName()) + ";"));
			wlist.add(NamedStatementListGenerator.getPutJsonResultMapWithSuccessAndDomainListPaging(7000L, 2, resultMap,
					vlist, pagesize, pagenum, pagecount));
			wlist.add(new Statement(8000L, 2, "return " + resultMap.getVarName() + ";"));
			method.setMethodStatementList(WriteableUtil.merge(wlist));

			return method;
		}
	}

	@Override
	public String generateControllerMethodString() throws Exception {
		if (this.denied)
			return null;
		else {
			Method m = this.generateControllerMethod();
			return m.generateMethodString();
		}
	}

	@Override
	public String generateControllerMethodStringWithSerial() throws Exception {
		if (this.denied)
			return null;
		else {
			Method m = this.generateControllerMethod();
			m.setContent(m.generateMethodContentStringWithSerial());
			m.setMethodStatementList(null);
			return m.generateMethodString();
		}
	}

	@Override
	public JavascriptBlock generateEasyUIJSButtonBlock() throws Exception {
		return null;
	}

	@Override
	public String generateEasyUIJSButtonBlockString() throws Exception {
		if (this.denied)
			return null;
		else {
			return generateEasyUIJSButtonBlock().generateBlockContentString();
		}
	}

	@Override
	public String generateEasyUIJSButtonBlockStringWithSerial() throws Exception {
		if (this.denied)
			return null;
		else {
			return generateEasyUIJSButtonBlock().generateBlockContentStringWithSerial();
		}
	}

	@Override
	public JavascriptMethod generateEasyUIJSActionMethod() throws Exception {
		if (this.denied)
			return null;
		else {
			Domain domain = this.domain;
			Var pagesize = new Var("pagesize", new Type("var"));
			Var pagenum = new Var("pagesize", new Type("var"));
			Var last = new Var("pagesize", new Type("var"));
			JavascriptMethod method = new JavascriptMethod();
			method.setSerial(200);
			method.setStandardName("listAll" + domain.getPlural() + "ByPage");
			Signature s1 = new Signature();
			s1.setName(pagesize.getVarName());
			s1.setPosition(1);
			s1.setType(new Type("var"));
			Signature s2 = new Signature();
			s2.setName(pagenum.getVarName());
			s2.setPosition(2);
			Signature s3 = new Signature();
			s3.setName(last.getVarName());
			s3.setPosition(3);
			s2.setType(new Type("var"));
			method.addSignature(s1);
			method.addSignature(s2);
			method.addSignature(s3);

			StatementList sl = new StatementList();
			sl.add(new Statement(1000, 0, "var myurl =\"../" + domain.getLowerFirstDomainName()
					+ domain.getControllerNamingSuffix() + "/listAll" + domain.getCapFirstPlural() + "ByPage\";"));
			sl.add(new Statement(2000, 0,
					"if (pagesize == undefined || pagesize == null || pagesize <= 0) pagesize=10;"));
			sl.add(new Statement(3000, 0, "if (pagenum == undefined || pagenum == null || pagenum <= 1) pagenum=1;"));
			sl.add(new Statement(4000, 0, "$.ajax({"));
			sl.add(new Statement(5000, 1, "type: \"post\","));
			sl.add(new Statement(6000, 1, "url: myurl,"));
			sl.add(new Statement(7000, 1, "data: {"));
			sl.add(new Statement(8000, 2, "pagesize:pagesize,"));
			sl.add(new Statement(9000, 2, "pagenum:pagenum,"));
			sl.add(new Statement(10000, 2, "last:last"));
			sl.add(new Statement(12000, 1, "},"));
			sl.add(new Statement(13000, 1, "dataType: 'json',"));
			sl.add(new Statement(14000, 1, "success: function(data, textStatus) {"));
			sl.add(new Statement(16000, 1, "},"));
			sl.add(new Statement(17000, 1, "complete : function(XMLHttpRequest, textStatus) {"));
			sl.add(new Statement(18000, 1, "},"));
			sl.add(new Statement(19000, 1, "error : function(XMLHttpRequest,textStatus,errorThrown) {"));
			sl.add(new Statement(20000, 2, "alert(\"Error:\"+textStatus);"));
			sl.add(new Statement(21000, 2, "alert(errorThrown.toString());"));
			sl.add(new Statement(22000, 1, "}"));
			sl.add(new Statement(23000, 0, "});"));

			method.setMethodStatementList(sl);
			return method;
		}
	}

	@Override
	public String generateEasyUIJSActionString() throws Exception {
		if (this.denied)
			return null;
		else {
			return generateEasyUIJSActionMethod().generateMethodString();
		}
	}

	@Override
	public String generateEasyUIJSActionStringWithSerial() throws Exception {
		if (this.denied)
			return null;
		else {
			return generateEasyUIJSActionMethod().generateMethodStringWithSerial();
		}
	}
}
